package com.pqtest.api.filter;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.java.Log;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.*;

//@Configuration
@WebFilter(filterName="oauthFilter",urlPatterns="/oauth/token")
@Log
public class ServletFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //String headEncoding = ((HttpServletRequest)servletRequest).getHeader("accept-encoding");

        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        //	this.Ctx.ResponseWriter.Header().Set("Access-Control-Allow-Origin", "*")       //允许访问源
        //	this.Ctx.ResponseWriter.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE")    //允许post访问
        //	this.Ctx.ResponseWriter.Header().Set("Access-Control-Allow-Headers", "Content-Type,Authorization") //header的类型
        //	this.Ctx.ResponseWriter.Header().Set("Access-Control-Max-Age", "1728000")
        //	this.Ctx.ResponseWriter.Header().Set("Access-Control-Allow-Credentials", "true")
        //	this.Ctx.ResponseWriter.Header().Set("Content-type", "application/json") //返回数据格式是json
//        resp.addHeader("Access-Control-Allow-Origin", "*");
//        resp.addHeader("Access-Control-Allow-Methods","POST, GET, PUT, OPTIONS, DELETE");
//        resp.addHeader("Access-Control-Allow-Headers", "Content-Type,Authorization");
//        resp.addHeader("Access-Control-Max-Age", "1728000");
//        resp.addHeader("Access-Control-Allow-Credentials", "true");
//        resp.addHeader("Content-type", "application/json");
        ResponseWrapper mResp = new ResponseWrapper(resp); // 包装响应对象 resp 并缓存响应数据
        filterChain.doFilter(req, mResp);
        byte[] bytes = mResp.getBytes(); // 获取缓存的响应数据
        String content = new String(bytes,"utf-8");
        JSONObject resjson = JSONObject.parseObject(content);
        if(resjson == null){
            return;
        }
        if(resjson.get("error") == null) {
            resjson.put("code", "ok");
        }else{
            resjson.put("code","fail");
        }


//        if(resjson.get("error") == null){
//            //TODO
//            //shall we store token to redis？
//            log.info(resjson.getString("access_token"));
//        }

        resp.getOutputStream().write(JSONObject.toJSONString(resjson).getBytes());

//            System.out.println("压缩前大小：" + bytes.length + req.getParameter("username"));
//            System.out.println("压缩前数据：" + new String(bytes,"utf-8"));
//
//            ByteArrayOutputStream bout = new ByteArrayOutputStream();
//            GZIPOutputStream gzipOut = new GZIPOutputStream(bout); // 创建 GZIPOutputStream 对象
//
//            gzipOut.write(bytes); // 将响应的数据写到 Gzip 压缩流中
//            gzipOut.flush();
//            gzipOut.close(); // 将数据刷新到  bout 字节流数组
//
//            byte[] bts = bout.toByteArray();
//            System.out.println("压缩后大小：" + bts.length);
//            resp.setHeader("Content-Encoding", "gzip"); // 设置响应头信息
//            resp.getOutputStream().write(bytes); // 将压缩数据响应给客户端
//        }
    }

    @Override
    public void destroy() {

    }

    public class ResponseWrapper extends HttpServletResponseWrapper {

        private ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        //        private HttpServletResponse response;
        private PrintWriter pwrite;

        public ResponseWrapper(HttpServletResponse response) {
            super(response);
            //this.response = response;
        }

        @Override
        public ServletOutputStream getOutputStream() throws IOException {
            return new MyServletOutputStream(bytes); // 将数据写到 byte 中
        }

        /**
         * 重写父类的 getWriter() 方法，将响应数据缓存在 PrintWriter 中
         */
        @Override
        public PrintWriter getWriter() throws IOException {
            try{
                pwrite = new PrintWriter(new OutputStreamWriter(bytes, "utf-8"));
            } catch(UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return pwrite;
        }

        /**
         * 获取缓存在 PrintWriter 中的响应数据
         * @return
         */
        public byte[] getBytes() {
            if(null != pwrite) {
                pwrite.close();
                return bytes.toByteArray();
            }

            if(null != bytes) {
                try {
                    bytes.flush();
                } catch(IOException e) {
                    e.printStackTrace();
                }
            }
            return bytes.toByteArray();
        }

        class MyServletOutputStream extends ServletOutputStream {
            private ByteArrayOutputStream ostream ;

            public MyServletOutputStream(ByteArrayOutputStream ostream) {
                this.ostream = ostream;
            }

            @Override
            public void write(int b) throws IOException {
                ostream.write(b); // 将数据写到 stream　中
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setWriteListener(WriteListener writeListener) {

            }
        }

    }
}


